Ext.define('CS.data.TreeStore', {
	extend: 'Ext.data.TreeStore',
	requires: ['CS.data.proxy.Custom', 'CS.data.reader.Tree'],

	rootPro: 'data',

	childrenPro: 'children',

	isAsync: false,

	constructor: function(config) {
		var me = this;

		config = CS.apply({}, config);

		config.defaultRootProperty = config.rootPro || me.rootPro;
		config.childrenPro = config.childrenPro || me.childrenPro;

		config.proxy = {
			type: 'custom',
			url: config.url,
			reader: {
				type: 'tree',
				childrenPro: config.childrenPro,
				needCheck: config.needCheck
			}
		};

		delete config.url;

		me.callParent([config]);
	},

	onNodeAdded: function(parent, node) {
		var me = this, proxy = me.getProxy(), reader = proxy.getReader(), data = node.raw
				|| node[node.persistenceProperty], dataRoot;

		Ext.Array.remove(me.removed, node);
		node.join(me);

		if (!node.isLeaf() && !me.lazyFill) {
			if (node.isRoot() || me.isAsync) {
				dataRoot = reader.getRoot(data);
			} else {
				dataRoot = data[me.childrenPro] || [];
			}
			if (dataRoot) {
				me.fillNode(node, reader.extractData(dataRoot));
				delete data[reader.root];
			}
		}

		if (me.autoSync && !me.autoSyncSuspended && (node.phantom || node.dirty)) {
			me.sync();
		}
	},

	setRootNode: function(root, preventLoad) {
		var me = this, model = me.model, idProperty = model.prototype.idProperty

		root = root || {};
		if (!root.isModel) {
			root = Ext.apply({}, root);
			Ext.applyIf(root, {
				id: me.defaultRootId,
				text: me.defaultRootText,
				allowDrag: false
			});
			if (root[idProperty] === undefined) {
				root[idProperty] = me.defaultRootId;
			}
			Ext.data.NodeInterface.decorate(model);
			root = Ext.ModelManager.create(root, model);
		} else if (root.isModel && !root.isNode) {
			Ext.data.NodeInterface.decorate(model);
		}

		me.getProxy().getReader().buildExtractors(true);

		me.tree.setRootNode(root);

		if (preventLoad !== true && !root.isLoaded() && me.autoLoad === true) {
			root.data.expanded = false;
			root.expand();
		}

		return root;
	},

	reload: function(options) {
		this.lastOptions = this.lastOptions || {};

		return this.load(Ext.apply(this.lastOptions, options));
	}

});
